package com.itheima.d4_collection_set;

import java.util.*;

/**
 * 目标：整体了解一下Set系列集合的特点。
 * collection接口（表示单列）的两个子接口：list接口，set接口
 * set接口有三个常用的实现类：hashset，linkedhashset，treeset
 *
 * Set系列集合特点： 无序：添加数据的顺序和获取出的数据顺序不一致；  不重复； 无索引;
 * HashSet : 无序、不重复、无索引。
 * LinkedHashSet：有序、不重复、无索引。
 * TreeSet：排序、不重复、无索引。
 *
 * 注意：
 * Set要用到的常用方法，基本上就是Collection提供的！！
 * 自己几乎没有额外新增一些常用功能！
 */
/*
    Collection API如下:
         - public boolean add(E e)：  把给定的对象添加到当前集合中 。
         - public void clear() :清空集合中所有的元素。
         - public boolean remove(E e): 把给定的对象在当前集合中删除。
         - public boolean contains(Object obj): 判断当前集合中是否包含给定的对象。
         - public boolean isEmpty(): 判断当前集合是否为空。
         - public int size(): 返回集合中元素的个数。
         - public Object[] toArray(): 把集合中的元素，存储到数组中。
 */
public class SetTest1 {
    public static void main(String[] args) {
        // 1、创建一个Set集合的对象，set系列集合的一个代表集合
        // 多态写法，创建了一个HashSet的集合对象 一行经典代码  HashSet: 无序 不重复 无索引
        //无序的意思不是说。每一次的输出的执行顺序都是随机的，一般来说就是无序一次
        //无序是说跟你输入的顺序不一样就叫无序，反之有序
        Set<Integer> set = new HashSet<>();
        set.add(111);
        set.add(777);
        set.add(888);
        set.add(888);
        set.add(555);
        set.add(333);
        set.add(777);
        set.add(666);
        System.out.println("---------HashSet无序： ");
        System.out.println("第一次： "+set);
        System.out.println("第二次： "+set);
        System.out.println(set.remove(555));
        System.out.println("删除555"+set);
        System.out.println("size方法："+set.size());
        System.out.println("contains777方法: "+set.contains(777));
        System.out.println(set.isEmpty());
        System.out.println("---------set.toArray方法---");
        Object[] array = set.toArray();
        System.out.print("直接输出array： ");
        System.out.println(array);
        System.out.print("调用arrays的toString方法： ");
        System.out.println(Arrays.toString(array));
        System.out.println("---------set.toArray(new String[set.size()])的写法---");
        //String[] array1 = set.toArray(new String[set.size()]);  //报错：ArrayStoreException
        Integer[] array1 = set.toArray(new Integer[set.size()]);
        System.out.println(Arrays.toString(array1));


        System.out.println();
        System.out.println("-------------LinkedHashSet是可以记住数据顺序，但是依旧无索引 不重复： ");

    /* Set系列集合特点：   无序：添加数据的顺序和获取出的数据顺序不一致；  不重复； 无索引;
            HashSet : 无序、不重复、无索引。
            LinkedHashSet：有序、不重复、无索引。
            TreeSet：排序、不重复、无索引。

LinkedHashSet的底层源码
public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable

        LinkedHashSet底层原理，继承自hashset
            依然是基于哈希表(数组、链表、红黑树)实现的。
            但是，相比hashset，它是进化版，每个元素都额外的多了一个双链表的机制记录它前后元素的位置。所以LinkedHashSet的有序是因为双链表记住了元素的添加顺序
            所以LinkedHashSet输出的时候，是通过双链表来找数据输出的，所以是是有序的
            如果没有双链表的话，比如hashset集合的输出，那就是从元素计算出来的哈希值求余后的底层数组和链表的索引，按照顺序输出
    */
        Set<Integer> set1 = new LinkedHashSet<>(); //  有序 不重复 无索引
//         Set<Integer> set = new TreeSet<>(); //  可排序（升序） 不重复 无索引
        set1.add(666);
        set1.add(555);
        set1.add(555);
        set1.add(888);
        set1.add(888);
        set1.add(777);
        set1.add(777);
        set1.add(999);
        set1.add(222);
        //set1.get();       无索引，报错，不支持调用索引相关方法
        System.out.println(set1);
        System.out.println(set1.size());
        System.out.println(set1.contains(666));
        System.out.println(set1.remove(222));

        System.out.println();
        System.out.println("---------treeSet  可排序（升序） 不重复 无索引： ");

        Set<Integer> set2 = new TreeSet<>(); //  可排序（升序） 不重复 无索引
        set2.add(111);
        set2.add(555);
        set2.add(777);
        set2.add(777);
        set2.add(222);
        set2.add(666);
        set2.add(999);
        System.out.println("可排序： "+set2);

    }
}
